#include "gamelib.h"

unsigned _stdcall MainLopp(void * argv)
{
	Snake * mySnake = (Snake *) argv;

	do
	{
		if(GetAsyncKeyState(VK_UP)) //http://msdn.microsoft.com/en-us/library/ms645540%28VS.85%29.aspx
		{
			WaitForSingleObject(Game_Settings::hMutex,INFINITE);
			mySnake->SetHeading(Snake::UP);
			ReleaseMutex(Game_Settings::hMutex);
		}
		if(GetAsyncKeyState(VK_LEFT))
		{
			WaitForSingleObject(Game_Settings::hMutex,INFINITE);
			mySnake->SetHeading(Snake::LEFT);
			ReleaseMutex(Game_Settings::hMutex);
		}
		if(GetAsyncKeyState(VK_RIGHT))
		{
			WaitForSingleObject(Game_Settings::hMutex,INFINITE);
			mySnake->SetHeading(Snake::RIGHT);
			ReleaseMutex(Game_Settings::hMutex);
		}
		if(GetAsyncKeyState(VK_DOWN))
		{
			WaitForSingleObject(Game_Settings::hMutex,INFINITE);
			mySnake->SetHeading(Snake::DOWN);
			ReleaseMutex(Game_Settings::hMutex);
		}
		if(GetAsyncKeyState(VK_ESCAPE))
			Game_Settings::FINISH = true;
		
		Sleep( ( Game_Settings::GAME_SPEED > 125 ) ? 125 : Game_Settings::GAME_SPEED );
	}while(!Game_Settings::FINISH);
	return 0;
}

bool CheckForFood(pair<int,int> snake_pos, Food &food, Snake &mysnake)
{
	if(snake_pos == food.Pos())
	{
		mysnake.AddSegment();
		food.Change();
		return true;
	}
	return false;
}

void UpdateDifficultyCheck(unsigned &food_eaten)
{
	static time_t cycle_start = 0;
	++food_eaten;
	
	//update player score
	int temp_score = SCORE_ALGORITHM;
	if(temp_score < 0 )
		Game_Settings::player_score +=  food_eaten % Game_Settings::LEVEL_DIF;
	else
		Game_Settings::player_score += temp_score;

	//Update status bar
	ixion::SetCursorPos(FOOD_POS_X,FOOD_POS_Y);
	cout << food_eaten;
	ixion::SetCursorPos(SCORE_POS_X,SCORE_POS_Y);
	cout << Game_Settings::player_score;

	if(food_eaten % Game_Settings::LEVEL_DIF == 0)
	{
		++Game_Settings::LEVEL;
		Game_Settings::GAME_SPEED = static_cast<unsigned>( Game_Settings::GAME_SPEED * double(GAME_SPEED_RATE) );
		//UUpdate Level status
		ixion::SetCursorPos(LEVEL_POS_X,LEVEL_POS_Y);
		cout << Game_Settings::LEVEL;
	
	}
	cycle_start = clock();
}

void Setup(Food &food, Snake &snake)
{

	ixion::SetBackgroundColor(ixion::DARK_GREEN);
	ixion::SetCursorPos(WIDTH_MIN,HEIGHT_MIN);
	for(int i = WIDTH_MIN; i < WIDTH + 3; i++)
	{
		cout << " ";
	}
	cout << endl;
	for(int i = HEIGHT_MIN + 1; i < HEIGHT + 2; i++)
	{
		ixion::SetCursorPos(WIDTH_MIN, HEIGHT_MIN + i);
		cout << " ";
		ixion::SetCursorPos(WIDTH + 2,HEIGHT_MIN + i);
		cout << " \n";
	}
	ixion::SetCursorPos(WIDTH_MIN,HEIGHT + 2);
	for(int i = WIDTH_MIN; i < WIDTH + 3; i++)
	{
		cout << " ";
	}
	ixion::SetBackgroundColor(ixion::BLACK);
	ixion::SetForegroundColor(ixion::WHITE);
	Food::MAX_HEIGHT = HEIGHT + 1;
	Food::MIN_HEIGHT = HEIGHT_MIN + 1;
	Food::MAX_WIDTH = WIDTH + 1;
	Food::MIN_WIDTH = WIDTH_MIN + 1;

	Snake::MAX_HEIGHT = HEIGHT + 1;
	Snake::MIN_HEIGHT = HEIGHT_MIN + 1;
	Snake::MAX_WIDTH = WIDTH + 1;
	Snake::MIN_WIDTH = WIDTH_MIN + 1;

	ixion::SetCursorPos(STATS_BAR_X,STATS_BAR_Y);
	cout <<"Lvl " << Game_Settings::LEVEL << "| Food " << 0 << " | Score " << 0;
}

void CreateHighScoreFile()
{
	ofstream outf(filename );
	for(int i = 0; i < MAX_HIGH_SCORES; i++)
	{
		outf << "NONE" << " " << 0 << endl;
	}
}
void LoadHighScores()
{
	ifstream inf(filename);
	ofstream  outf;
	if(!inf)
	{
		inf.close();
		inf.clear();
		CreateHighScoreFile();
		inf.open(filename);
	}
	string fname;
	unsigned fscore;
	int i = HIGH_SCORE_BOARD_Y;
	
	while(inf >> fname >> fscore)
	{
		ostringstream oss;
		ixion::SetCursorPos(HIGH_SCORE_BOARD_X,i++);
		oss << (i - 2);
		cout << left<< setw(4) << (oss.str() + ". ")  << setw(10) << fname << setw(10) << fscore;
		
		
	}
}


void CheckHighScores(unsigned score)
{
	ifstream inf(filename);
	ofstream  outf;
	if(!inf)
	{
		inf.close();
		inf.clear();
		CreateHighScoreFile();
		inf.open(filename);
	}
	string fname, name;
	unsigned fscore;
	vector< pair<string,unsigned> > myHighScores;
	bool NEWHS = false;
	while(inf >> fname >> fscore)
	{
		if(fscore < score && !NEWHS)
		{
			ixion::SetCursorPos(NEW_HIGH_SCORE_X,NEW_HIGH_SCORE_Y);
			cout << "NEW HIGH SCORE";
			ixion::SetCursorPos(NEW_HIGH_SCORE_NAME_X,NEW_HIGH_SCORE_NAME_Y);
				cout << "NAME:";
			cin >> name;
			myHighScores.push_back(make_pair(name,score) );
			NEWHS = true;
		}
		myHighScores.push_back(make_pair(fname,fscore) );
	}
	sort(myHighScores.begin(),myHighScores.end(),[=](pair<string,unsigned> l, pair<string,unsigned> r){
		return l.second > r.second;
	});

	outf.open(filename);
	for(unsigned i = 0; i < MAX_HIGH_SCORES && i < myHighScores.size(); i++)
	{
		outf << myHighScores[i].first << " " << myHighScores[i].second << endl;
	}


}
void game_reset()
{	 
	 Game_Settings::player_score = 0;
	 Game_Settings::FINISH = false;
	 Game_Settings::GAME_SPEED = Game_Settings::MASTER_GAMESPEED;
	 Game_Settings::LEVEL = Game_Settings::MASTER_GAME_LEVEL;
	 Game_Settings::LEVEL_DIF = Game_Settings::MASTER_LEVEL_DIF;
	 system("CLS");
	 LoadHighScores();
}